<?php
define('MIN_FQDN_LENGTH', 4);
define('MAX_FQDN_LENGTH', 255);
define('MAX_LPART_LENGTH', 64);

class Tools {

//
// Проверки
//

// Строка - логика
    public static function is_boolstr( $s ) {
        $s = strtolower($s);
        return is_string( $s ) && ( $s == 'true' || $s == 'false' );
    }

// Высляет интервал в ремени в указаных единицах
// См. date_default_timezone_set
	public static function how_many( $uni, $dfrom, $dto = null ) {
		if( !isset($dto) ) $dto= time();
		
		$ftm = is_int( $dto ) ? $dto : ( is_string( $dto ) ? strtotime($dto) : false );
		$stm = is_int( $dfrom ) ? $dfrom : ( is_string( $dfrom ) ? strtotime($dfrom) : false );
		if( is_bool( $stm ) || is_bool($ftm) ) return false;
		
		$interv = $ftm - $stm;
		
		switch( $uni ) {
			case 'day':		$result = $interv/86400; break;
			case 'hour':	$result = $interv/3600; break;
			case 'min':		$result = $interv/60; break;
			case 'sec':		$result = $interv; break;
			default:		$result = false; break;
		}
		return $result;
	}
	
// Все ли члены массива числовые	
    public static function is_numeric_array( $arr ) {
        $res = true;
        if( !count($arr) ) return false;
        foreach( $arr as $value ) {
            if( !is_numeric($value) ) { $res = false; break; }
        }
        return $res;
    }

// Приведение номера телефона к цифровому виду '0123456789'
	public static function phone_clearing( $phone ) {
		$phone = preg_replace( '/[^0-9]/u', '', $phone );
		if( strlen( $phone ) != 10 ) return false;
		return $phone;
	}
	
// Приведение номера телефона к виду '(XXX) XXX-XX-XX'
	public static function phone_humanity( $phone ) {
		if( strlen( $phone ) != 10 || !ctype_digit($phone) ) return false;
		return '('.substr($phone,0,3).') '.substr($phone,3,3).'-'.substr($phone,6,2).'-'.substr($phone,8,2);
	}

// Проверка правильности даты. Допустимые форматы: ДД.ММ.ГГГГ и ГГГГ-ММ-ДД
// На выходе всегда будет ГГГГ-ММ-ДД либо FALSE
	public static function check_date( $dt ) {
		if( !isset( $dt ) || strlen($dt) != 10 ) return false;
		$result = $day = $month = $year = "";
		if( preg_match( '/^(\d\d)\.(\d\d)\.(\d\d\d\d)$/', $dt, $dmy ) ) {
			$day = $dmy[1]; $month = $dmy[2]; $year = $dmy[3];
		}
		elseif( preg_match( '/^(\d\d\d\d)-(\d\d)-(\d\d)$/', $dt, $dmy ) ) {
			$day = $dmy[3]; $month = $dmy[2]; $year = $dmy[1];
		}
		if( checkdate( (int)$month, (int)$day, (int)$year ) ) 
			$result = $year.'-'.$month.'-'.$day;
		return $result ? $result : false;
	}
	
// Преобразование даты для поиска в БД.
// ДД.ММ.ГГГГ -> ГГГГ-ММ-ДД
// ММ.ГГГГ -> ГГГГ-ММ
// ГГГГ -> ГГГГ
	public static function date_to_search_str( $idt ) {
		if( !$idt ) return '';
		$odt = '';
		if( preg_match( '/^(\d\d)\.(\d\d)\.(\d\d\d\d)$/', $idt, $dmy ) )
			$odt = $dmy[3].'-'.$dmy[2].'-'.$dmy[1];
		elseif( preg_match( '/^(\d\d)\.(\d\d\d\d)$/', $idt, $dmy ) )
			$odt = $dmy[2].'-'.$dmy[1];
		elseif( preg_match( '/^(\d\d\d\d)$/', $idt, $dmy ) )
			$odt = $dmy[1];
		return $odt;
	}
	
// Ковертирует запись ГГГГ-ММ-ДД в ДД.ММ.ГГГГ
// !!! Корректность даты не проверяется
	public static function str_iso2local_date( $idt ) {
		if( !$idt ) return '';
		return substr($idt,8,2).'.'.substr($idt,5,2).'.'.substr($idt,0,4);
	}
	
// Check e-mail address
    public static function is_mail_address( $mail ) {
        if( !is_string($mail) || $mail === '' )
        return false;
        
        $mail = strtolower($mail);
        $uxo = strpos( $mail, '@');
        
        $lpart = '';
        $domain = '';
    
        $result = false;
        while( true ) {
    
            if( !$uxo ) break;    
            
            if( $uxo > 0 && $uxo < strlen($mail) - 1 ) {
                $lpart = substr( $mail,0,$uxo );
                $domain = substr( $mail,$uxo+1);
            
                $mlen = strlen( $lpart );
                if( $mlen > MAX_LPART_LENGTH ) break;
                if( !preg_match( '/^[a-z0-9_](?:[0-9a-z._+-]*[a-z0-9_])?$/', $lpart ) )
                    break;
            
                $mlen = strlen( $domain );        
                if( $mlen > MAX_FQDN_LENGTH || $mlen < MIN_FQDN_LENGTH ) 
                    break;
            
                $result = preg_match( '/^(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z*]{2,}$/', $domain );
                    break;
            }
        
            break;
        }
        
        return $result;
    }

// Check domain name
	public static function is_domain_name( $domain ) {
		if( !is_string($domain) || $domain === '' )
			return false;
	
		$domain = strtolower($domain);

		$mlen = strlen( $domain );
		if( $mlen > MAX_FQDN_LENGTH || $mlen < MIN_FQDN_LENGTH )
			return false;
	    
		return preg_match( '/^(?:[0-9a-z]+(?:[0-9a-z-]*[0-9a-z])?\.)+[a-z]{2,}$/', $domain );
	}

// preg_match('/^(http|https|ftp)://([A-Z0-9][A-Z0-9_-]*(?:.[A-Z0-9][A-Z0-9_-]*)+):?(d+)?/?/i', $url)
// Check domain name
	public static function is_url_address( $domain ) {
		if( !is_string($domain) || $domain === '' )
			return false;
	
		$domain = strtolower($domain);

		$mlen = strlen( $domain );
		if( $mlen > MAX_FQDN_LENGTH || $mlen < MIN_FQDN_LENGTH )
			return false;
	    
		$result = preg_match( '/^(?:https?\:\/\/)?(?:[0-9a-z]+(?:[0-9a-z-]*[0-9a-z])?\.)+[a-z]{2,}'.
				'($|\/.*|\:\d{2,5}$|\:\d{2,5}\/.*)/', $domain, $p );
		return $result;
	}


// Ajax ли это запрос	
	public static function isAjax() {
		return ( isset($_SERVER['HTTP_REFERER']) && isset($_SERVER['HTTP_X_REQUESTED_WITH']) && 
			preg_match("|^http(s)?://".$_SERVER['SERVER_NAME']."/|", $_SERVER['HTTP_REFERER']) &&
			strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' ) ? true : false;
	}

//
// Формирование JSON ответа
//
    public static function json_response( $errmess='', $errcode=0, $data = null ) {
        $json_arr = array( 
                'errcode'=>$errcode, 
                'errmess'=>$errmess,
                'data'=>$data 
                );
        header("Content-type: text/script;charset=utf-8");
        echo json_encode( $json_arr );   
    }
    

//
// Generate password
//
	public static function passw_gen( $max ) {
		$chars="qazxswedcvfrtgbnhyujmkiolp1234567890QAZXSWEDCVFRTGBNHYUJMKIOLP";
		$size=strlen($chars)-1;

		$password='';
		while($max--)
			$password.=$chars[rand(0,$size)];
			
		return $password;
	}

//
// Sent plain/text e-mail
//
    public static function mail_utf8($from, $to, $subject = '(No subject)', $message = '', $header = '') {
        $header_ = 'MIME-Version: 1.0' . "\r\n" . 'Content-type: text/plain; charset=UTF-8' . "\r\n";
        mail($to, '=?UTF-8?B?'.base64_encode($subject).'?=', $message, $header_ . $header, "-f".$from);
    } 


//
// Формирование полного УРЛа выполняющегося скрипта.
//
  public static function getFullUrl() {
	return
		(isset($_SERVER['HTTPS']) ? 'https://' : 'http://').
    	(isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').
    	(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].
    	(isset($_SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] === 443 ||
    	$_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).
    	$_SERVER['SCRIPT_NAME'];
  }

//
// Формирование базового УРЛа выполняющегося скрипта.
//
  public static function getBaseUrl() {
	return
   		(isset($_SERVER['HTTPS']) ? 'https://' : 'http://').
   		(isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').
   		(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].
   		(isset($_SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] === 443 ||
   		$_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).
   		substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
  }

}  
?>